package com.sn.author.monitor;


import com.alibaba.fastjson.JSON;
import com.sn.author.domain.taskEntity.TaskModel;
import com.sn.author.monitor.handler.Handler;
import com.sn.author.monitor.handler.HandlerFactory;
import com.sn.author.redis.RedisKeyBuild;
import com.sn.author.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;

/**
 * @Author xiaom
 * @Date 2020/9/22 14:34
 * @Version 1.0.0
 * @Description <任务监听器>
 **/
@Slf4j
public class TaskListenerHandler extends ListenerHandler{

    public TaskListenerHandler(String taskType) {
        super(taskType);
    }

    /**
     * 监听redis队列 获取执行任务
     */
    @Override
    public void run() {
        while (true){
            try {
                doWork();
                sleep(100);
            } catch (Exception e) {
                log.error("执行工作线程失败 taskType:{} errorMessage:{}",super.taskType,e.getMessage());
                e.printStackTrace();
            }
        }
    }

    private void doWork() throws Exception {
        //获取任务
        TaskModel taskModel = getTaskByTool();
        if(taskModel == null){
            log.debug("【任务类型】:{} 无任务.",taskType);
            return;
        }
        log.info("【监听到任务】【任务类型】:{} 任务参数:${}",taskType,JSON.toJSONString(taskModel));
        validParams(taskModel);
        //远程调用抖音api登录
        remoteDyServer(taskModel);
    }

    private void validParams(TaskModel taskModel) throws Exception {

        if(taskModel.getTaskType() == null){
            throw new Exception("任务模型异常,因为缺少taskType字段");
        }
        if(taskModel.getTaskId() == null){
            throw new Exception("任务模型异常,因为缺少taskId字段");
        }
    }

    private void remoteDyServer(TaskModel taskModel) throws Exception {
        //识别工作类型
        Class<? extends Handler> handlerCls = HandlerFactory.buildHandler(taskModel.getTaskType());
        Constructor constructor = handlerCls.getConstructor(TaskModel.class);
        Handler handler = (Handler) constructor.newInstance(taskModel);
        //交给对应处理器执行
        handler.execute();
    }

    private TaskModel getTaskByTool(){
        Object obj = RedisUtil._REDIS_MODULE.bpop(RedisKeyBuild.buildTaskQueueKey(taskType));
        if(obj == null){
            return null;
        }
        return JSON.parseObject(obj.toString(),TaskModel.class);
    }
}
